package com.univocity.trader.strategy;

import com.univocity.trader.candles.*;

import java.util.*;

/**
 * 一个用于创建高效 Strategy 的指标组。{@link IndicatorGroup} 中的所有指标共享一个共同的聚合器 {@link Aggregator}，
 * 它负责将更高分辨率的蜡烛图合并成较低分辨率的蜡烛图 {@link Candle}（例如，将五个 1 分钟的蜡烛合并成一个 5 分钟的蜡烛），
 * 这样同一时间框架内的组中任何指标都会收到相同的合并蜡烛。
 *
 * @see IndicatorStrategy
 * @see StrategyMonitor
 * @see Indicator
 * @see Aggregator
 */
public abstract class IndicatorGroup {

    public Indicator[] indicators;

    /**
     * 初始化此组中所有指标（通过 {@link #getAllIndicators()} 返回）以使用相同的聚合器 {@link Aggregator}。
     *
     * @param parent 所有指标将使用的聚合器
     */
    public final void initialize(Aggregator parent) {
        if (indicators != null) {
            return;
        }
        Set<Indicator> allIndicators = getAllIndicators();
        if (allIndicators == null) {
            indicators = new Indicator[0];
            return;
        }

        indicators = allIndicators.toArray(new Indicator[0]);
        for (int i = 0; i < indicators.length; i++) {
            indicators[i].initialize(parent);
        }
    }

    /**
     * 遍历此组中的所有指标，并调用它们的 {@link Indicator#accumulate(Candle)} 方法，以便它们可以更新自己的状态。
     * 在所有指标更新后，将调用方法 {@link #candleAccumulated(Candle)} 以通知实现此类类的指标组状态可能已更改。
     * @param candle 一个由 {@link com.univocity.trader.Exchange} 返回的最新价格详细信息
     */
    public final void accumulate(Candle candle) {
        for (int i = 0; i < indicators.length; i++) {
            indicators[i].accumulate(candle);
        }
        candleAccumulated(candle);
    }

    /**
     * 回调方法，用于通知子类一个 {@link Candle} 被累积，并且此组中的指标可能有一个新状态。
     * 默认情况下什么也不做。
     *
     * @param candle 一个由 {@link com.univocity.trader.Exchange} 返回的最新价格详细信息
     */
    public void candleAccumulated(Candle candle) {

    }

    /**
     * 返回此组中所有的指标，如果有的话。
     *
     * @return 此组中所有指标的集合。可能是null。
     */
    protected abstract Set getAllIndicators();
}